home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 6 / Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso / 026a / dbivbin.zip / DBIVBIN.C next >
C/C++ Source or Header  |  1991-02-12  |  9KB  |  263 lines

  1. /*─── DBIVBIN.C ───────────────────────────────────────────────────────────
  2.    Template for QC 2.5 routines intended for conversion by MAKEBIN.EXE
  3.    to BINs suitable for use with dBASE IV. The authorship of MAKEBIN by
  4.    Michael Day is gratefully acknowledged.
  5.  
  6.    This template has 2 uses:
  7.  
  8.    1. With Make Option set to debug
  9.       it creates a standalone .EXE file, that is easily debugged.
  10.       Set test parameters below.
  11.  
  12.    2. With Make Option set to Release
  13.       it creates an .EXE file that can then be converted by MAKEBIN.EXE:
  14.  
  15.       MAKEBIN dbivbin.exe
  16.  
  17.    This template has been tested only with QC 2.5, small memory model.
  18. ─────────────────────────────────────────────────────────────────────────*/
  19.  
  20. /* Common code */
  21. extern unsigned int _near _cdecl _psp;
  22.  
  23. /* define NULL pointer value */
  24. #define NULL    ((void *)0)
  25.  
  26. #define MK_FARPTR(hi,low) (*((unsigned long _far *)(((unsigned long)(hi) \
  27.                           << 16) | (unsigned)(low))))
  28.  
  29. struct ipc_struct
  30. {
  31.     char bipc[4];  /* ipc->bipc contains 'BIPC' if the BIN properly loaded */
  32.     unsigned int oldflgs;   /* flags on entry to the BIN file */
  33.     unsigned int oldax;     /* AX register on entry to the BIN file */
  34.     unsigned int oldbx;     /* BX register on entry to the BIN file */
  35.     unsigned int oldcx;     /* CX register on entry to the BIN file */
  36.     unsigned int olddx;     /* DX register on entry to the BIN file */
  37.     unsigned int oldsi;     /* SI register on entry to the BIN file */
  38.     unsigned int olddi;     /* DI register on entry to the BIN file */
  39.     unsigned int oldds;     /* DS register on entry to the BIN file */
  40.     unsigned int oldes;     /* ES register on entry to the BIN file */
  41.     unsigned int oldbp;     /* BP register on entry to the BIN file */
  42.     unsigned long OldStk;   /* SS:SP registers, pointer to stack on entry  */
  43.     unsigned long WrkPtr;   /* CS:IP, pointer to current Entry address */
  44.     unsigned long WrkStk;   /*  pointer to stack on exit */
  45.     unsigned int BinDS;     /* DS seg on exit from BIN file */
  46.     unsigned int BinSS;     /* SS seg on exit from BIN file */
  47.     unsigned long LoadPtr;  /* pointer to original entry point of BIN */
  48.     unsigned long LoadStk;  /* pointer to original stack location of BIN  */
  49.     unsigned int PspSeg;    /* current PSP seg of BIN file */
  50.     unsigned int OldPsp;    /* caller's PSP segment */
  51.     unsigned int PrgSiz;    /* Total size of bin file in paragraphs */
  52. };
  53.  
  54. struct ipc_struct _far * ipc; /* pointer to interface structure */
  55. int argc;                     /* number of parameters */
  56. char _far * argv[8];          /* array of far pointers to parameters */
  57. struct ipc_struct _far * ipcinit( void );
  58.  
  59. #ifndef NDEBUG    /* this code for debugging */
  60.  
  61. /* debug function prototypes */
  62. void savestate( void );
  63. void verifystate( void );
  64.  
  65. struct ipc_struct ipcdebug;   /* dummy ipc structure */
  66. unsigned int argvlengths[8];  /* array of parameter lengths */
  67.  
  68. /*─────────────────────────────────────────────────────────────────────────
  69.  TEST parameters
  70.  set these  as appropriate for debugging
  71. ─────────────────────────────────────────────────────────────────────────*/
  72. argc = 2;                                        /* number of parameters */
  73. char _far *p1 = "Z";                           /* 1'st parameter       */
  74. char _far *p2 = "BARqsw.DBF";                       /* etc.                 */
  75. char _far *p3 = "";
  76. char _far *p4 = "";
  77. char _far *p5 = "";
  78. char _far *p6 = "";
  79. char _far *p7 = "";
  80. /*───────────────────────────────────────────────────────────────────────*/
  81. #endif
  82.  
  83.  
  84. /*─────────────────────────────────────────────────────────────────────────
  85. *** Actual routine(s) go here ********************************************
  86. ─────────────────────────────────────────────────────────────────────────*/
  87.  
  88. /*─────────────────────────────────────────────────────────────────────────
  89.  
  90. BIN to deactivate/activate DB4 production MDX. Requires 2 parameters,
  91. 1'st is either capital 'Z' or 'U', 2'nd is database file name.
  92. 'Z' as 1'st parameter will write 0h to offset 28 of the DBF's header,
  93. deactivating any production MDX. 'U' as 1'st parameter will write 1h
  94. to offset 28 of the DBF's header, activating any production MDX.
  95. Syntax:
  96. LOAD mdxzap
  97. lc_result=CALL("mdxzap","Z","myfile.dbf")
  98. The CALL function will return the following codes:
  99. '0' == Success
  100. '1' == Some problem with the BIN itself.
  101. '2' == Wrong number of parameters
  102. '3' == Parameter 1 not 'Z' or 'U'
  103. '4' == Could not open DBF
  104. '5' == Could not write to DBF
  105.  
  106. ─────────────────────────────────────────────────────────────────────────*/
  107.  
  108. #include <stdio.h>
  109. #include <stdlib.h>
  110. #include <fcntl.h>
  111. #include <io.h>
  112. #include <sys\types.h>
  113. #include <sys\stat.h>
  114. #include <string.h>
  115.  
  116. void main( void )
  117. {
  118.     /* variable declarations */
  119.     int fh;
  120.     char byte_to_write;
  121.     char dbf_name[50];
  122.     char parm1[2];
  123.     char far *strpos;
  124.     int count;
  125.  
  126.  
  127.     if( ipcinit() == NULL ) /* NULL = invalid interface record */
  128.         *argv[1] = '1';
  129.     else
  130.     {
  131.  
  132. #ifndef NDEBUG    /* store parameter lengths if debugging */
  133.         savestate();
  134. #endif
  135.         if(argc != 2)
  136.             *argv[1] = '2';
  137.         else
  138.         {
  139.             /* copy argv[2] to near string */
  140.             count = 0;
  141.             for(strpos = argv[2]; *strpos != 0; strpos++)
  142.             {
  143.                 dbf_name[count] = *strpos;
  144.                 ++count;
  145.             }
  146.             dbf_name[count] = 0;
  147.  
  148.             /* copy argv[1] to near string */
  149.             parm1[0] = *argv[1];
  150.             parm1[1] = 0;
  151.  
  152.             /* validate parameter 1 */
  153.             switch(*parm1)
  154.             {
  155.             case 'Z':
  156.                 byte_to_write = 0;
  157.                 break;
  158.             case 'U':
  159.                 byte_to_write = 1;
  160.                 break;
  161.             default:
  162.                 *argv[1] = '3';
  163.             }
  164.  
  165.             if (*argv[1] != '3')
  166.             {
  167.                 /* open and write DBF file */
  168.                 if( (fh = open(dbf_name, O_BINARY|O_WRONLY)) == -1 )
  169.                     *argv[1] = '4';
  170.                 else
  171.                 {
  172.                     if (lseek(fh,28L,SEEK_SET) != 28L)
  173.                         *argv[1] = '5';
  174.                     else
  175.                     {
  176.                         if (write(fh,&byte_to_write,1) != 1)
  177.                             *argv[1] = '5';
  178.                         else
  179.                             *argv[1] = '0';
  180.                     }
  181.                     close(fh);
  182.                 }
  183.             }
  184.         }
  185.     }
  186.  
  187. #ifndef NDEBUG    /* check & print parameters if debugging */
  188.     verifystate();
  189. #endif
  190.  
  191. }
  192.  
  193. /*─────────────────────────────────────────────────────────────────────────
  194. *** End of routine ********************************************************
  195. ─────────────────────────────────────────────────────────────────────────*/
  196.  
  197. #ifndef NDEBUG    /* this code for debugging */
  198.  
  199. /* initialize dummy ipc structure for debugging */
  200. struct ipc_struct _far * ipcinit( void )
  201. {
  202.     ipc = &ipcdebug;
  203.     ipc->bipc[0] = 'B';
  204.     ipc->bipc[1] = 'I';
  205.     ipc->bipc[2] = 'P';
  206.     ipc->bipc[3] = 'C';
  207.     argv[1] = p1;
  208.     argv[2] = p2;
  209.     argv[3] = p3;
  210.     argv[4] = p4;
  211.     argv[5] = p5;
  212.     argv[6] = p6;
  213.     argv[7] = p7;
  214.     return(ipc);
  215. }
  216.  
  217. /* save parameter lengths */
  218. void savestate( void )
  219. {
  220.     int i;
  221.     for( i = 1; i <= argc; i++)
  222.         argvlengths[i] = _fstrlen(argv[i]);
  223. }
  224.  
  225. /* check parameter lengths and print them */
  226. void verifystate( void )
  227. {
  228.     int i;
  229.     for( i = 1; i <= argc; i++)
  230.     {
  231.         if( _fstrlen(argv[i]) != argvlengths[i] )
  232.             printf( "\nWarning! Parm%d's length has changed from %d to %d!", \
  233.                     i, argvlengths[i], _fstrlen(argv[i]) );
  234.         printf( "\nParm%d: %s", i, argv[i] );
  235.     }
  236. }
  237.  
  238. #else
  239.  
  240. /* real ipcinit function */
  241. struct ipc_struct _far * ipcinit( void )
  242. {
  243.     int parm_offset, i;
  244.     ipc = (struct ipc_struct _far *)MK_FARPTR(_psp-2,0);
  245.     if (ipc->bipc[0] == 'B' && ipc->bipc[1] == 'I' &&\
  246.         ipc->bipc[2] == 'P' && ipc->bipc[3] == 'C')
  247.     {
  248.         argc = ipc->oldcx; /* dBASE4 stores the number of parms in CX */
  249.         parm_offset = 0;
  250.         for( i = 1; i <= 7; i++)
  251.         {
  252.             /* dBASE4 sets ES:DI to point to an array
  253.                of far pointers to parameters.         */
  254.             argv[i] = (char _far *)MK_FARPTR(ipc->oldes,ipc->olddi+parm_offset);
  255.             parm_offset += 4;
  256.         }
  257.         return(ipc);
  258.     }
  259.     else
  260.         return(NULL);       /* NULL = invalid interface record */
  261. }
  262. #endif
  263.